#ifndef DBMGR_H
#define DBMGR_H

#include <QtSql>
#include <string>
#include <map>
#include <vector>
#include <memory>

struct TypeInfo
{
    int id;
    std::string suffix;
};
struct FileInfo
{
    int id;
    std::string fullpath;
    std::string basename;
    int type;
    int thirdparty;
};

struct DepInfo
{
    int id;
    int left;
    int right;
};

class DBMgr
{
public:
    enum DB_ERR
    {
        ERR_OK = 0,
        ERR_INVALID,    // The DB doesn't contain all tables.
        ERR_EXIST,      // There is already a DB in the path.
        ERR_NOT_EXIST,  // There is no DB in the path.
        ERR_OTHER
    };

    enum DB_TABLE
    {
        TABLE_TYPE,
        TABLE_FILE,
        TABLE_DEP
    };

    DBMgr();
    ~DBMgr();

    DB_ERR createDB(std::string &path);
    DB_ERR openDB(std::string &path);

    bool transaction() {return m_db.transaction();}
    bool commit() {return m_db.commit();}

    bool isOpen() { return m_db.isOpen(); }

    bool insertType(std::string &suffix);
    int insertFile(std::string &fullpath, std::string &basename, int type, int isdirectory, int parent, int thirdparty);
    bool insertDep(int left, int right);

    int insertFiles(std::vector<std::string> &fullpaths, std::vector<std::string> &basenames, std::vector<int> &types, std::vector<int> &isdirectorys, std::vector<int> &parents, std::vector<int> &thirdpartys);

    std::shared_ptr<std::vector<TypeInfo>> queryType(int id, std::string &suffix);
    std::shared_ptr<std::vector<FileInfo>> queryFile(int id, std::string &fullpath, std::string &basename, int type, int isdirectory, int parent, int thirdparty);
    std::shared_ptr<std::vector<DepInfo>> queryDep(int id, int left, int right);

    std::shared_ptr<std::vector<TypeInfo>> queryAllType();
    std::shared_ptr<std::vector<TypeInfo>> queryTypeBySuffix(std::string &suffix);

    std::shared_ptr<std::vector<FileInfo>> queryAllFile();
    std::shared_ptr<std::vector<FileInfo>> queryFileById(int id);
    std::shared_ptr<std::vector<FileInfo>> queryFileByBasename(std::string &basename);
    std::shared_ptr<std::vector<FileInfo>> queryFileByFullpath(std::string &fullpath);
    std::shared_ptr<std::vector<FileInfo>> queryFileByType(int type);

    std::shared_ptr<std::vector<DepInfo>> queryAllDep();
    std::shared_ptr<std::vector<DepInfo>> queryDepByLeft(int left);
    std::shared_ptr<std::vector<DepInfo>> queryDepByRight(int right);

private:
    const static std::map<DB_TABLE, std::string> TABLE_NAME_MAP;
    const static std::map<DB_TABLE, std::string> TABLE_CREATESQL_MAP;
    std::string m_currentDB;
    QSqlDatabase m_db;
};

#endif // DBMGR_H
